package me.flyray.bsin.server.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import me.flyray.bsin.constants.ResponseCode;
import me.flyray.bsin.context.BsinServiceContext;
import me.flyray.bsin.domain.entity.AgentCard;
import me.flyray.bsin.domain.entity.Conversation;
import me.flyray.bsin.domain.entity.ConversationMessage;
import me.flyray.bsin.exception.BusinessException;
import me.flyray.bsin.facade.service.ConversationService;
import me.flyray.bsin.infrastructure.mapper.ConversationMapper;
import me.flyray.bsin.infrastructure.mapper.ConversationMessageMapper;
import me.flyray.bsin.infrastructure.mapper.AgentCardMapper;
import me.flyray.bsin.mybatis.utils.Pagination;
import me.flyray.bsin.security.contex.LoginInfoContextHelper;
import me.flyray.bsin.security.domain.LoginUser;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.client.apache.dubbo.annotation.ShenyuDubboService;
import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
import org.apache.shenyu.client.apidocs.annotations.ApiModule;
import org.apache.shenyu.client.dubbo.common.annotation.ShenyuDubboClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;
import org.springframework.transaction.annotation.Transactional;

import static me.flyray.bsin.constants.ResponseCode.*;

@Slf4j
@ShenyuDubboService(path = "/conversation", timeout = 6000)
@ApiModule(value = "conversation")
public class ConversationServiceImpl implements ConversationService {

    @Autowired
    private ConversationMapper conversationMapper;

    @Autowired
    private ConversationMessageMapper conversationMessageMapper;

    @Autowired
    private AgentCardMapper agentCardMapper;

    @ApiDoc(desc = "add")
    @ShenyuDubboClient("/add")
    @Override
    public Conversation add(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        Conversation conversation = BsinServiceContext.getReqBodyDto(Conversation.class, requestMap);
        Optional.ofNullable(conversation.getTenantId())
                .or(() -> Optional.ofNullable(loginUser.getTenantId()))
                .ifPresentOrElse(
                        conversation::setTenantId,
                        () -> { throw new BusinessException(ResponseCode.TENANT_ID_NOT_ISNULL); }
                );
        conversation.setBizRoleType(loginUser.getBizRoleType());
        conversation.setBizRoleTypeNo(loginUser.getBizRoleTypeNo());
        conversationMapper.insert(conversation);
        return conversation;
    }

    @ApiDoc(desc = "delete")
    @ShenyuDubboClient("/delete")
    @Override
    public void delete(Map<String, Object> requestMap) {
        String serialNo = MapUtils.getString(requestMap, "serialNo");
        if (conversationMapper.deleteById(serialNo) == 0){
            throw new BusinessException(ID_NOT_ISNULL);
        }
    }

    @ApiDoc(desc = "getDetail")
    @ShenyuDubboClient("/getDetail")
    @Override
    public Conversation getDetail(Map<String, Object> requestMap) {
        String serialNo = MapUtils.getString(requestMap, "serialNo");
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String bizRoleTypeNo = null;
        if (serialNo == null) {
            bizRoleTypeNo = loginUser.getBizRoleTypeNo();
            if(bizRoleTypeNo == null){
                throw new BusinessException(ResponseCode.CUSTOMER_NO_NOT_ISNULL);
            }
        }
        Conversation conversationMessage = conversationMapper.selectOne(new LambdaQueryWrapper<Conversation>()
                .eq(Conversation::getTenantId, loginUser.getTenantId())
                .eq(StringUtils.isNotBlank(serialNo), Conversation::getSerialNo, serialNo)
                .eq(StringUtils.isNotBlank(bizRoleTypeNo), Conversation::getBizRoleTypeNo, bizRoleTypeNo));
        return conversationMessage;
    }

    /**
     * 根据登录人查询
     * 并取按照agent_no分组
     * @param requestMap
     * @return
     */
    @ApiDoc(desc = "getPageList")
    @ShenyuDubboClient("/getPageList")
    @Override
    public IPage<?> getPageList(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        Conversation conversation = BsinServiceContext.getReqBodyDto(Conversation.class, requestMap);
        Object paginationObj =  requestMap.get("pagination");
        Pagination pagination = new Pagination();
        BeanUtil.copyProperties(paginationObj,pagination);
        Page<Conversation> page = new Page<>(pagination.getPageNum(),pagination.getPageSize());
        IPage<Conversation> pageList = conversationMapper.selectPageByGroup(page, loginUser.getTenantId(), loginUser.getBizRoleTypeNo());
        return pageList;
    }

    @ApiDoc(desc = "getList")
    @ShenyuDubboClient("/getList")
    @Override
    public List<Conversation> getList(Map<String, Object> requestMap) {
        Conversation conversation = BsinServiceContext.getReqBodyDto(Conversation.class, requestMap);
        String tenantId = (String) requestMap.get("tenantId");
        LambdaQueryWrapper<Conversation> warapper = new LambdaQueryWrapper<>();
        warapper.eq(Conversation::getTenantId, tenantId);
        List<Conversation> agentCardList = conversationMapper.selectList(warapper);
        return agentCardList;
    }

    /**
     * 给智能推送消息 - 优化版本，支持批量操作和事务
     */
    @ApiDoc(desc = "messagePush")
    @ShenyuDubboClient("/messagePush")
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void messagePush(Map<String, Object> requestMap) {
        log.info("开始推送消息给租户 {} 的智能体", requestMap);
        try {
            LoginUser loginUser = LoginInfoContextHelper.getLoginUser();

            String tenantId = StringUtils.defaultIfBlank(MapUtils.getString(requestMap, "tenantId"), LoginInfoContextHelper.getTenantId());
            String bizRoleTypeNo = StringUtils.defaultIfBlank(MapUtils.getString(requestMap, "bizRoleTypeNo"), LoginInfoContextHelper.getBizRoleType());
            String bizRoleType = StringUtils.defaultIfBlank(MapUtils.getString(requestMap, "bizRoleType"), LoginInfoContextHelper.getBizRoleType());

            // 从请求参数中获取推送消息内容
            String messageContent = MapUtils.getString(requestMap, "content");
            String messageTitle = MapUtils.getString(requestMap, "title");
            
            // 验证必填参数
            if (StringUtils.isBlank(messageContent)) {
                throw new BusinessException(ID_NOT_ISNULL);
            }
            if (StringUtils.isBlank(messageTitle)) {
                throw new BusinessException(ID_NOT_ISNULL);
            }
            
            log.info("开始推送消息给租户 {} 的智能体列表", tenantId);
            
            // 1、找到智能体列表 - 根据租户ID获取可用的智能体
            LambdaQueryWrapper<AgentCard> agentQueryWrapper = new LambdaQueryWrapper<>();
            agentQueryWrapper.eq(AgentCard::getTenantId, tenantId)
                           .eq(AgentCard::getStatus, 1) // 启用状态
                           .eq(AgentCard::getIssueFlag, 1); // 已发布
            List<AgentCard> agentList = agentCardMapper.selectList(agentQueryWrapper);
            
            log.info("找到 {} 个可用的智能体", agentList.size());
            
            if (agentList.isEmpty()) {
                log.warn("租户 {} 没有可用的智能体", tenantId);
                return;
            }
            
            // 2、为每个智能体创建对话和消息
            agentList.forEach(agent -> createConversationWithMessage(agent, tenantId, bizRoleTypeNo, 
                bizRoleType, messageTitle, messageContent));
            
            log.info("消息推送完成");
            
        } catch (Exception e) {
            log.error("消息推送过程中发生错误: {}", e.getMessage(), e);
            throw new BusinessException(ID_NOT_ISNULL);
        }
    }

    /**
     * 为智能体创建对话和消息 - 简洁版本
     */
    private void createConversationWithMessage(AgentCard agent, String tenantId, String bizRoleTypeNo,
                                             String bizRoleType, String messageTitle, String messageContent) {
        // 创建对话
        Conversation conversation = buildConversation(agent, tenantId, bizRoleTypeNo, bizRoleType, messageTitle);
        conversationMapper.insert(conversation);

        // 创建消息
        ConversationMessage message = buildMessage(conversation, tenantId, bizRoleTypeNo, bizRoleType, messageContent);
        conversationMessageMapper.insert(message);

        // 更新对话最后消息信息
        updateLastMessage(conversation, message, messageContent);
        conversationMapper.updateById(conversation);
    }

    private Conversation buildConversation(AgentCard agent, String tenantId, String bizRoleTypeNo,
                                         String bizRoleType, String messageTitle) {
        Conversation conversation = new Conversation();
        conversation.setTenantId(tenantId);
        conversation.setBizRoleTypeNo(bizRoleTypeNo);
        conversation.setBizRoleType(bizRoleType);
        conversation.setAgentNo(agent.getSerialNo());
        conversation.setAgentName(agent.getName());
        conversation.setAgentIconUrl(agent.getIconUrl());
        conversation.setStatus(1);
        conversation.setTitle(messageTitle);
        conversation.setUnreadCount("1");
        conversation.setDelFlag(false);
        conversation.setCreateTime(new Date());
        return conversation;
    }

    private ConversationMessage buildMessage(Conversation conversation, String tenantId, String bizRoleTypeNo,
                                           String bizRoleType, String messageContent) {
        ConversationMessage message = new ConversationMessage();
        message.setSerialNo(UUID.randomUUID().toString().replace("-", ""));
        message.setTenantId(tenantId);
        message.setAgentNo(conversation.getAgentNo());
        message.setBizRoleTypeNo(bizRoleTypeNo);
        message.setBizRoleType(bizRoleType);
        message.setConversationNo(conversation.getSerialNo());
        message.setRoleType("3");
        message.setContent(messageContent);
        message.setContentType("text");
        message.setCreateTime(new Date());
        message.setDelFlag(0);
        return message;
    }

    private void updateLastMessage(Conversation conversation, ConversationMessage message, String messageContent) {
        conversation.setLastMessageNo(message.getSerialNo());
        conversation.setLastMessageContent(messageContent.length() > 50 ? 
            messageContent.substring(0, 50) + "..." : messageContent);
    }

}
